/*============================================================================*/
/*                                                                            */
/* cortest.c                                                                  */
/*                                                                            */
/* This is an implementation of the program for testing the algorithm         */
/* for detecting the corners in digital images that was developed at          */
/* VSB-Technical University of Ostrava. The theory of the algorithm and       */
/* other details are available at                                             */
/*                                                                            */
/* http://www.cs.vsb.cz/sojka/cordet/presentation.html                        */
/*                                                                            */
/* The program is mainly intended as a tool for verifying whether the         */
/* function detectCorners was compiled properly on your platform. The program */
/* should be launched witch a parameter, which is the name of a script file   */
/* that defines all the parameters of the test. You should obtain three script*/
/* files "test1.scr", "test2.scr", and "test3.scr" that launch the three tests*/
/* published in the above stated URL. You should run all of them and check    */
/* whether you obtain the correct output lists of corners (the expected lists */
/* are in the files "check1.txt", "check2.txt", "check3.txt"). The script     */
/* files are text files. Have a look at those that come along with this       */
/* program and take them as examples how to set the parameters for the        */
/* detector and how to create your own script files. You can find a detailed  */
/* description of the parameters as well as some practical advice how to set  */
/* their values in "cordet.h".                                                */
/*                                                                            */
/* If you need some further assistance or if you have some comments, please   */
/* be so kind and contact me at "eduard.sojka@vsb.cz".                        */
/*                                                                            */
/* This version of implementation is from 2 April 2003. Please, contact me    */
/* if you read this message substantially later. I may be able to provide     */
/* you with a newer version.                                                  */
/*                                                                            */
/* (c) Eduard Sojka, 2003                                                     */
/*                                                                            */
/*============================================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "utils.h"
#include "cordet.h"
#define  MAX_NUM_OF_CORNER_COORDS 20000  /* maximal number of coords we accept*/
#define  LINE_LENGTH 256

/*----------------------------------------------------------------------------*/
/* The function readScriptFile reads and analyses the script file. It returns */
/* the values of parameters that were set in the script file.                 */

int readScriptFile( char *scriptFileName, char *imageFileName,
                    char *cornerListFileName, int *halfPsgMaskSize,
                   float *angleThresh, float *gradSizeThresh,
                   float *apparenceThresh, float *meanGradSizeThresh,
                   float *inertiaRadiusThresh, float *sigmaD,
                   float *sigmaR, int *halfExtMaskSize, int *options){

    FILE *inp; char atom[LINE_LENGTH];
    if((inp = fopen( scriptFileName, "rt" )) != NULL){
      readAtom(inp,atom); if (strcmp(atom, "cortest") != 0 ) return -2;
      if (readAtom(inp,imageFileName)      != 0) return -3;
      if (readAtom(inp,cornerListFileName) != 0) return -4;
      if (readAtom(inp,atom) != 0) return  -5; *halfPsgMaskSize    = atoi(atom);
      if (readAtom(inp,atom) != 0) return  -6; *angleThresh        = atof(atom);
      if (readAtom(inp,atom) != 0) return  -7; *gradSizeThresh     = atof(atom);
      if (readAtom(inp,atom) != 0) return  -8; *apparenceThresh    = atof(atom);
      if (readAtom(inp,atom) != 0) return  -9; *meanGradSizeThresh = atof(atom);
      if (readAtom(inp,atom) != 0) return -10; *inertiaRadiusThresh= atof(atom);
      if (readAtom(inp,atom) != 0) return -11; *sigmaD             = atof(atom);
      if (readAtom(inp,atom) != 0) return -12; *sigmaR             = atof(atom);
      if (readAtom(inp,atom) != 0) return -13; *halfExtMaskSize    = atoi(atom);
      if (readAtom(inp,atom) != 0) return -14; *options            = atoi(atom);
      fclose(inp); return 0;
    } else return -1;
}
/*----------------------------------------------------------------------------*/

#define freeMem \
  if (byteImage  != NULL) free(byteImage);\
  if (floatImage != NULL) free(floatImage);\
  if (corners    != NULL) free(corners);\

int main( int argc, char **argv ) {

    char imageFileName[LINE_LENGTH], cornerListFileName[LINE_LENGTH];
    int  xImageSize, yImageSize, numImagePixels,
         halfPsgMaskSize, halfExtMaskSize, options,
        *corners, numCorners, i, problem;
    unsigned char *byteImage;
    float *floatImage, noiseGradSizeThresh, angleThresh, apparThresh,
           gradSizeThresh, inertiaRadiusThresh, sigmaD, sigmaR;
    clock_t start, stop;

    if (argc != 2){
        printf( "\nsyntax:\n\n" );
        printf( "  cortest file\n\n" );
        printf( "  The 'file' contains the script for the test. You should \n");
        printf( "  obtain the script files 'test1.scr', 'test2.scr', and\n");
        printf( "  'test3.scr' along with this program. You can also create\n");
        printf( "  your own script files.\n\n");
        printf( "example: cortest test1.scr\n\n");
        return( -1 );
    }

    printf("\n");
    printf("======================================================\n");
    printf("| Testing the new agorithm for detecting the corners |\n");
    printf("======================================================\n");

    if ((problem = readScriptFile( argv[1], imageFileName,
       cornerListFileName, &halfPsgMaskSize, &angleThresh, &noiseGradSizeThresh,
       &apparThresh, &gradSizeThresh, &inertiaRadiusThresh, &sigmaD,
       &sigmaR, &halfExtMaskSize, &options)) != 0 ){
           printf("  Problem with the script file '%s' (line %i).\n\n",
                     argv[1], (-problem-1)); exit(-1);
    }

    byteImage = loadImageFromTGA( imageFileName, &xImageSize, &yImageSize);
    if (byteImage == NULL){
        printf("  Problems with loading image from '%s'.\n\n", imageFileName);
        free(byteImage); exit(-1);
    }

    numImagePixels = xImageSize*yImageSize;
    floatImage = (float *)malloc(numImagePixels * sizeof(floatImage[0]));
    corners    = (int *)malloc(MAX_NUM_OF_CORNER_COORDS * sizeof(corners[0]));
    if ((floatImage == NULL)||(corners == NULL)){
        printf("  There is not enough memory for solving the problem.\n\n");
        freeMem; exit(-1);
    }
    printf("  The image from '%s' is now being processed.\n", imageFileName );
    for (i = 0; i < numImagePixels; i ++) floatImage[i] = byteImage[i];

    Cordet c;
    start = clock();

    numCorners = c.detectCorners( floatImage, xImageSize, yImageSize,
      halfPsgMaskSize, angleThresh, noiseGradSizeThresh, apparThresh,
      gradSizeThresh, inertiaRadiusThresh, sigmaD, sigmaR, halfExtMaskSize,
      options, corners, MAX_NUM_OF_CORNER_COORDS );

    stop = clock();
    
    if (numCorners == -1){
        printf("  There was not enough memory for solving the problem.\n\n");
        freeMem; exit(-1);}
    if (numCorners == -2){
        printf("  Warning: Not all the corners were placed to the\n\n");
        printf("  output list since the array is not big enough.\n\n");
        numCorners = MAX_NUM_OF_CORNER_COORDS / 2;
    } 
    printf("  Result: %li corners were found ", numCorners);
    printf("in %g seconds.\n", (stop-start)/(float)CLOCKS_PER_SEC);

    if (saveCornerList(cornerListFileName, corners, numCorners) >= 0)
      printf("  The list of corners was saved into '%s'.\n",cornerListFileName);
    else printf(" Problems with writing to '%s'.\n", cornerListFileName);

    freeMem;
    printf("======================================================\n\n");

    return 0;

}
/*============================================================================*/



